Skip to content

model(deepseek-v4): DeepSeek-V4-Pro is the SAME architecture as V4-Flash — gate the config descent (#504) - #511

Merged
localai-bot merged 3 commits into
mainfrom
row/MODEL-V4-PRO-VARIANT
Aug 12, 2026
Merged

model(deepseek-v4): DeepSeek-V4-Pro is the SAME architecture as V4-Flash — gate the config descent (#504)#511
localai-bot merged 3 commits into
mainfrom
row/MODEL-V4-PRO-VARIANT

Conversation

@localai-bot

Copy link
Copy Markdown
Collaborator

Closes #504. Spec: .agents/specs/deepseek-v4-pro.md. Row: MODEL-TEXT-deepseek-v4-deepseek-v4-for-causal-lm.

What this establishes

deepseek-ai/DeepSeek-V4-Pro is DeepseekV4ForCausalLM / model_type: deepseek_v4 — the same architecture as DeepSeek-V4-Flash, which this row already supports. No architecture work is owed. Pro is a config variant of this row, not a new model row, and this PR adds the gate that keeps that claim honest.

A key-by-key diff of both shipped config.json files has zero new and zero removed keys. Every difference is a scaled value: hidden 4096→7168, layers 43→61, heads 64→128, experts 256→384, moe_inter 2048→3072, q_lora 1024→1536, o_groups 8→16, index_topk 512→1024, routed_scaling 1.5→2.5, compress_ratios[0:2] [0,0][128,128]. head_dim 512, hc_mult 4, num_hash_layers 3, sqrtsoftplus/noaux_tc, expert_dtype: fp4 and the rest are identical. Heads-per-output-LoRA-group is 8 on both.

Grounded three ways, not asserted

Upstream (pin 555967922, vLLM 0.26.0.dev0): one vllm/models/deepseek_v4/ package serves both models, every dimension read off config (nvidia/model.py:535-679, attention.py:193-211, :708). Compressor presence is compress_ratio > 1 (attention.py:334) over max(1, compress_ratios[layer_id]) (:209), and the compressor asserts compress_ratio in [4, 128] (compressor.py:171). Ratio 0 maps to 1 and therefore means no compressor — the same polarity as our has_compressor(l) = ratio != 0 (deepseek_v4.h:127). I read the whole ~38-file package for literal Flash dimensions; there are none.

Real checkpoints: normalizing layer and expert indices out of both model.safetensors.index.json files gives 98 distinct tensor-name patterns on each side, with zero unique to either (Pro 145116 tensors, Flash 69187). Predicting compressor/indexer layers from compress_ratios alone reproduces both checkpoints exactly:

predicted actual
Flash (43L) 41 compressor / 21 indexer 41 / 21
Pro (61L) 61 / 30 61 / 30

Pro's layers 0-1 carry the 4-tensor ratio-128 compressor group where Flash has none — the single structural difference between the configs.

Our side: the only shape assertion in 6930 lines of V4 sources is head_dim == 512 (deepseek_v4_weights.cpp:173), which Pro satisfies; all dims come off config (deepseek_v4.cpp:1725-1731) and all CUDA shared memory is extern __shared__.

The gate

tests/vllm/models/test_deepseek_v4_pro_variant.cpp — 5 cases / 197 assertions, CPU-only, no fixture, no GPU, no download. It drives ParseDeepseekV4Params with the real Pro values and the real compress_ratios arrays, asserts the 61/30 and 41/21 counts and the layer-0/1 delta directly, and carries Flash as the control arm so no assertion can be satisfied by a Flash-shaped implementation.

RED evidence by mutation, tree restored byte-for-byte (md5sum -c OK) after each:

mutation site result
p.num_hidden_layers = 43 deepseek_v4_weights.cpp:111 3 cases / 5 assertions FAIL
has_compressor gains layer >= 2 && deepseek_v4.h:127 2 cases / 3 assertions FAIL
p.o_groups = 8 deepseek_v4_weights.cpp:132 2 cases / 3 assertions FAIL

Restored → 5/5 · 197 SUCCESS. All nine V4 suites green on the same build: scaffold 62, dsa 38, compressor 164, moe 716, mhc 125, forward 26, mtp 29, gguf_load 931, pro_variant 197.

Hardware verdict — recorded, not worked around

1.599T params: 805 GiB native, 864 GiB for nvidia/DeepSeek-V4-Pro-NVFP4, 534.7 GiB for the smallest real GGUF (teamblobfish Q2_K-XL). One GB10 is 119 GiB, so Q2 is ~4.5x over and the ~400 GB 2-bit floor means no quantization closes it. The pinned oracle needs the same memory, so Pro's load/forward/strict gates are PENDING an external resource — a named blocker, not a correctable finding. Flash already needed 2 Sparks; Pro needs roughly 5-8 at Q2.

Gate status

scripts/agent-preflight.sh --staged at the pushed SHA a532bbe2: every gate ok except test_cpu_x86_llamacpp_floor, including commit-trailers, trailer suites, doc-checkpoint, now-current and all record checkers.

That one red is box contention, not this change, and I verified it rather than asserting it:

  • the pristine base SHA fdd45263 — zero changes of mine — fails the same test with NO_QUIET_WINDOW after 30s (busy=118% load=44.97), driven by two concurrent sessions' builds;
  • the same test came back ok in this worktree during an earlier run when load briefly dropped;
  • the harness reads none of the four paths in this diff.

Docs

No lifecycle transition, so no STATUS/BENCHMARKS write is owed. Docs surfaces are deliberately untouched: no user-visible capability changed, because Pro cannot be run on this hardware.

Filed while assessing this

#505DsaTopkKernel (cuda_deepseek_v4.cu:639-641) sizes chosen[512] / picked[64] by literal while index_topk is 512 (Flash) / 1024 (Pro). Latent today only because dsa_dense = (be.gguf != nullptr) (deepseek_v4.cpp:668) forces the indexer off on the real path; it becomes a silent thread-stack overflow once the real-geometry DSA residual lands. Spec §5 records the upstream candidate-window contract (v1/attention/backends/mla/indexer.py:270-290 — full causal prefix in compressed-key space) for whoever builds that out.

Review note

This branch was authored in a coordinating session, so it has not had an independent review pass. It needs a fresh reviewer on the immutable head before merge — in particular someone to re-run the three mutations above and confirm the restored tree is byte-identical.

🤖 Generated with Claude Code

mudler added 3 commits August 12, 2026 17:35
…ash -- gate the config descent's shape-generality (#504)

`deepseek-ai/DeepSeek-V4-Pro` is `DeepseekV4ForCausalLM` / `model_type:
deepseek_v4`. A key-by-key diff of both shipped `config.json` files has ZERO new
and ZERO removed keys: hidden 4096->7168, layers 43->61, heads 64->128, experts
256->384, moe_inter 2048->3072, q_lora 1024->1536, o_groups 8->16, index_topk
512->1024, routed_scaling 1.5->2.5, and compress_ratios[0:2] [0,0]->[128,128].
Everything else is identical, including head_dim 512, hc_mult 4, num_hash_layers
3, sqrtsoftplus/noaux_tc and expert_dtype fp4. No architecture work is owed: Pro
is a CONFIG VARIANT of this row, not a new model row.

Grounded three ways rather than asserted.

Upstream (pin 555967922, vLLM 0.26.0.dev0): one `vllm/models/deepseek_v4/`
package serves both, every dimension read off `config` (`nvidia/model.py:535-679`,
`attention.py:193-211`, `:708`). Compressor presence is `compress_ratio > 1`
(`attention.py:334`) over `max(1, compress_ratios[layer_id])` (`:209`), and the
compressor asserts `compress_ratio in [4, 128]` (`compressor.py:171`). Ratio 0
maps to 1 and so means NO compressor -- the same polarity as our
`has_compressor(l) = ratio != 0` (`deepseek_v4.h:127`). Read the whole ~38-file
package for literal Flash dimensions: none.

Real checkpoints: normalizing layer/expert indices out of both
`model.safetensors.index.json` files gives 98 distinct tensor-name patterns on
each side with ZERO unique to either (Pro 145116 tensors, Flash 69187).
Predicting compressor/indexer layers from `compress_ratios` alone reproduces both
exactly -- Flash 41/21, Pro 61/30 -- and Pro's layers 0-1 carry the 4-tensor
ratio-128 compressor group where Flash has none.

Our side: the only shape assertion in 6930 lines of V4 sources is
`head_dim == 512` (`deepseek_v4_weights.cpp:173`), which Pro satisfies; all dims
come off config (`deepseek_v4.cpp:1725-1731`) and all CUDA shared memory is
`extern __shared__`.

The new CPU gate (5 cases / 197 assertions, no fixture, no GPU) drives
`ParseDeepseekV4Params` with the real Pro values and the REAL compress_ratios
arrays, asserts the 61/30 and 41/21 counts and the layer-0/1 delta, and carries
Flash as the control arm so nothing can be satisfied Flash-shaped.

RED evidence by mutation, tree restored byte-for-byte (`md5sum -c` OK) after each:
hardcoding `num_hidden_layers = 43` reds 3 cases / 5 assertions; adding
`layer >= 2 &&` to `has_compressor` reds 2 / 3; hardcoding `o_groups = 8` reds
2 / 3. Restored: 5/5 197 SUCCESS. All nine V4 suites green on the same build --
scaffold 62, dsa 38, compressor 164, moe 716, mhc 125, forward 26, mtp 29,
gguf_load 931, pro_variant 197.

Hardware verdict recorded, not worked around: 1.599T params is 805 GiB native,
864 GiB for `nvidia/DeepSeek-V4-Pro-NVFP4`, and 534.7 GiB for the smallest real
GGUF (`teamblobfish` Q2_K-XL). One GB10 is 119 GiB, so Q2 is ~4.5x over and the
~400 GB 2-bit floor means no quantization closes it. The pinned oracle needs the
same memory, so Pro's load/forward/strict gates are PENDING an external resource
-- a named blocker, not a correctable finding.

No lifecycle transition, so no STATUS/BENCHMARKS write is owed. Docs surfaces are
untouched deliberately: no user-visible capability changed, because Pro cannot be
run on this hardware.

Filed while assessing this: #505 -- `DsaTopkKernel` sizes `chosen[512]`/
`picked[64]` by literal while `index_topk` is 512 (Flash) / 1024 (Pro). Latent
today only because `dsa_dense = (be.gguf != nullptr)` (`deepseek_v4.cpp:668`)
forces the indexer off on the real path; it becomes a silent thread-stack
overflow once the real-geometry DSA residual lands. Spec section 5 records the
upstream candidate-window contract (`indexer.py:270-290`, full causal prefix in
COMPRESSED-key space) for whoever builds that out.

`test_cpu_x86_llamacpp_floor` is red in preflight from box contention, not from
this change: the pristine base SHA fdd4526 fails the same test with
NO_QUIET_WINDOW at load 43+ driven by two concurrent sessions' builds, and the
harness reads none of the four paths here.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
No overlap with the four paths this branch touches; re-gated after the merge.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
No overlap with the four paths this branch touches; re-gated after the merge.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
@localai-bot
localai-bot merged commit 6db04e7 into main Aug 12, 2026
19 of 23 checks passed
localai-bot added a commit that referenced this pull request Aug 12, 2026
…_topk -- remove the literal bounds (#505)

Lands the #505 fix: DsaTopkKernel sized `bool chosen[512]` and `int64_t
picked[64]` by literal while index_topk is 512 (V4-Flash) / 1024 (V4-Pro).
MEASURED on dgx.casa (GB10, sm_121a): the pre-fix kernel at Flash's own width
takes `cudaStreamDestroy: an illegal memory access` and SIGABRTs; after the
two-pass threshold rewrite the suite is 23/23 with 83913/83913 assertions and
0 skipped, re-verified from the merged tree with CUTLASS + FlashAttention-2
hard-verified in that run's own configure log.

The fix removes the bounds rather than asserting them, so there is no
configurable limit left to outgrow, and it drops the O(topk^2) emit sort.

FRESH REVIEW: PASS. An independent reviewer reproduced both the defect and the
fix on real sm_121a hardware, fuzzed 3,000,081 shapes across three independent
implementations (host reference, kernel transcription, and its own O(n^2)
rank-count oracle) with ZERO divergence, and ran a 12-row device mutation table.
It found no blocking issue and 6 non-blocking findings, addressed in a follow-up.
Notably it confirmed the tie-heavy case is uniquely load-bearing: it is the only
case that catches a tie-break inversion or a value-only threshold.

CI: windows-msvc-cpu and windows-msvc-vulkan are red at the repo-wide BASELINE,
not from this change -- the same two jobs fail on #539, #541 and on #511 which
already merged, and this PR's own log shows every target building with no
`error C####`, failing instead in the release-packaging PowerShell step.

Merged on direct developer instruction after the requested review pass.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
localai-bot added a commit that referenced this pull request Aug 13, 2026
…opk, and correct two guard-comment overclaims (#552)

Lands the six findings from the fresh review of #505, which returned PASS after
failing to find any input where the two-pass threshold selection diverges from
`DsaTopkSelect` -- 3,000,081 fuzzed shapes across three independent
implementations, zero divergence.

CODE: `DsaTopkLaunch` now checks `cudaGetLastError()` after the launch and refuses
non-positive `topk` to match the host reference, which previously asserted while
the device arm silently returned an empty vector.

TESTS: two new device cases. One drives the window clamps -- under-run, over-run,
both at once, and an in-range control -- which nothing exercised before. One
asserts BOTH arms refuse topk=0 and topk=-1.

PROSE: the `w < topk` guard comment claimed to defend against a NaN row writing
past its own row. That cannot occur: pass 2's predicate is satisfied by exactly
rank(th) <= topk elements and a NaN never satisfies it either. Corrected to
belt-and-braces, bounded by construction. "Strictly cheaper" is now scoped to a
comparison with the old kernel, not fitness for the real geometry.

REFUTED IN FLIGHT: finding 4 held that the launch check would make the next fault
attributable to this launch. The arm built to demonstrate it disproved it -- the
pre-fix kernel WITH the check still reports `cudaStreamDestroy: an illegal memory
access`, because a stack-overflow fault is asynchronous while `cudaGetLastError()`
covers launch-configuration errors. The check is kept and its comment now says
what it actually does; claiming otherwise would have repeated finding 1's defect
inside the change that exists to correct one.

DEVICE ARMS on dgx.casa (GB10 sm_121a), each a fresh nvcc rebuild from a pristine
kernel with the binary mtime verified to advance, scoped with `-tc=` never `-ts=`,
under `flock $HOME/gpu.lock`: baseline 6/6 SUCCESS; no_topk_guard FAILURE;
no_ws_clamp exit=134 CRASHED; no_we_clamp 1052 failed assertions; no_launch_check
SUCCESS (unobservable by construction); prefix_with_check exit=134; restored full
suite 25/25 with 90062 assertions, 0 skipped, SUCCESS. Both new cases have teeth
against the mutation each was written for.

CPU 25/25 and 13/13, preflight fully clean including the contention-sensitive
floor harness. Windows MSVC red is the repo-wide baseline (same two jobs fail on
#539, #541 and on #511 which already merged; no `error C####`, the failure is the
release-packaging PowerShell step).

Merged on direct developer instruction.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
@localai-bot
localai-bot deleted the row/MODEL-V4-PRO-VARIANT branch August 13, 2026 08:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

DeepSeek-V4-Pro is the same architecture as V4-Flash: record the variant and prove the config descent is shape-generic

2 participants